package ali

import (
	"encoding/json"
	"fmt"
	"gitee.com/goexc/ddns/utils"
	"gitee.com/goexc/ddns/variables"
	"github.com/aliyun/alibaba-cloud-sdk-go/services/alidns"
	"strings"
)

var err error
var dnsClient *alidns.Client
var domains []string

type IAliDnsService interface {
	/*域名管理接口*/
	//4.3 获取子域名解析记录列表
	DescribeSubDomainRecords(domains string)
	//4.6 修改解析记录
	UpdateDomainRecord()
}

type AliDnsService struct {
	client *alidns.Client
}

func NewAliDnsService(RegionId, AccessKeyId, AccessKeySecret string) (IAliDnsService, error) {
	//获取解析记录列表
	if dnsClient, err = alidns.NewClientWithAccessKey(RegionId, AccessKeyId, AccessKeySecret); err != nil {
		return nil, err
	}

	return &AliDnsService{
		client: dnsClient,
	}, nil
}

// 4.3 获取子域名解析记录列表
// 名称			类型		必选		示例值				描述
// SubDomain		String	是		a.www.example.com	以参数SubDomain为a.www.example.com为示例：
//
//	如果参数DomainName为空，则查询域名为example.com、主机名为”a.www“的解析记录。
//	如果参数DomainName为 www.example.com，则查询域名为www.example.com、主机名为 "a"的解析记录。
//	如果参数DomainName为 a.www.example.com，则查询域名为a.www.example.com、主机名为 "@"的解析记录。
//
// Lang			String	否		en					语言。
// UserClientIp	String	否		1.1.1.1				用户端IP。
// PageNumber	Long	否		1					当前页数，起始值为1，默认为1。
// PageSize		Long	否		20					分页查询时设置的每页行数，最大值500，默认为20。
// Type			String	否		MX					解析记录类型。若不传值，则返回子域名对应的全部解析记录类型。
//
//	解析类型包括(不区分大小写)：A、MX、CNAME、TXT、REDIRECT_URL、FORWORD_URL、NS、AAAA、SRV。
//
// Line			String	否		default				解析线路。
// DomainName	String	否		example.com			域名名称。
func (d *AliDnsService) DescribeSubDomainRecords(domains string) {
	var req *alidns.DescribeSubDomainRecordsRequest
	var res *alidns.DescribeSubDomainRecordsResponse
	req = alidns.CreateDescribeSubDomainRecordsRequest()

	subdomains := strings.Split(strings.TrimSpace(domains), ",")
	for _, subdomain := range subdomains {
		req.SubDomain = subdomain
		if res, err = d.client.DescribeSubDomainRecords(req); err != nil {
			variables.Msg <- fmt.Sprintf("获取子域名解析记录列表失败:%s", err.Error())
			alierr, ok := utils.ParsingAliErr(err)
			if !ok {
				msg, _ := json.Marshal(&alierr)
				variables.Msg <- fmt.Sprintf("阿里云获取子域名解析记录列表失败:%s", string(msg))
				return
			}
			return
		}

		if res.IsSuccess() { //入库
			variables.Msg <- fmt.Sprintf("获取子域名解析记录列表成功")
			variables.Msg <- fmt.Sprintf(res.GetHttpContentString())
			switch res.TotalCount {
			case 0:
				variables.Msg <- fmt.Sprintf("没有查找到子域名：%s", subdomain)
			default:
				for idx := range res.DomainRecords.Record {
					variables.Domains[res.DomainRecords.Record[idx].RR+"."+res.DomainRecords.Record[idx].DomainName] = &res.DomainRecords.Record[idx]
				}
			}
		} else {
			variables.Msg <- fmt.Sprintf("获取子域名解析记录列表不成功：%#v", res)
		}
	}
}

// 4.6 修改解析记录
// 名称			类型		必选		示例值				描述
// RecordId		String	是		9999985				解析记录的ID 。此参数在添加解析时会返回，在获取域名解析列表时会返回。
// RR			String	是		www					主机记录。如果要解析@.exmaple.com，主机记录要填写”@”，而不是空。
// Type			String	是		A					解析记录类型，A、NS、MX、TXT、CNAME、SRV、AAAA、CAA、显性URL转发、隐性URL转发。
// Value			String	是		202.106.0.20		记录值。
// Lang			String	否		en					语言。
// Line			String	否		default				解析线路，默认为default。参见解析线路枚举。
// Priority		Long	否		1					MX记录的优先级，取值范围：[1,50]。记录类型为MX记录时，此参数必需，MX 优先级的数值越低，优先级别就越高。
// TTL			Long	否		600					解析生效时间，默认为600秒（10分钟）。参见TTL定义说明。
// UserClientIp	String	否		1.1.1.1				用户端IP。
func (d *AliDnsService) UpdateDomainRecord() {
	var req *alidns.UpdateDomainRecordRequest
	var res *alidns.UpdateDomainRecordResponse
	req = alidns.CreateUpdateDomainRecordRequest()

	ip, err := utils.IPGlobal()
	if err != nil {
		variables.Msg <- fmt.Sprintf("公网IP获取失败：%s", err.Error())
		return
	}

	for key := range variables.Domains {
		variables.Msg <- fmt.Sprintf("当前主机公网IP:%s, 当前子域名[%s]IP:%s", ip, key, variables.Domains[key].Value)
		if strings.TrimSpace(ip) == "" {
			continue
		}
		if variables.Domains[key].Value != ip {
			variables.Msg <- fmt.Sprintf("域名：%s", key)
			req.RecordId = variables.Domains[key].RecordId
			req.RR = variables.Domains[key].RR
			req.Type = variables.Domains[key].Type
			req.Value = ip //子域名对应的IP记录值。
			req.Line = variables.Domains[key].Line
			req.UserClientIp = ip //客户端ip

			if res, err = d.client.UpdateDomainRecord(req); err != nil {
				variables.Msg <- fmt.Sprintf("修改域名DNS服务器失败：%s", err.Error())
				alierr, ok := utils.ParsingAliErr(err)
				if !ok {
					msg, _ := json.Marshal(&alierr)
					variables.Msg <- fmt.Sprintf("阿里云Error解析失败:%s", string(msg))
					return
				}
				return
			}
			if res.IsSuccess() { //入库
				variables.Msg <- fmt.Sprintf("修改域名DNS服务器成功")
				variables.Domains[key].Value = ip
			} else {
				variables.Msg <- fmt.Sprintf("修改域名DNS服务器不成功:%s", res.String())
			}
		}
	}

	//domains := strings.Split(strings.TrimSpace(os.Getenv("DOMAINS")), ",")
}
